#include "qpipelinehost.h"

#include "../property/qabstractproperty.h"
#include "../qpropertyfactory.h"
#include "../qcommonstruct.h"
#include "../qhostfactory.h"

#include <QPainter>
#include <QGradient>
#include <QPaintEngine>
#include <QVector>

int g_speed[]={
  50,
  100,
  150,
  200,
  300,
  400,
  500,
  800,
  1000,
  2000,
  5000
};

QPipelineWidth::QPipelineWidth(QWidget *parent) :
    QWidget(parent),
    m_point(0),
    m_timer(new QTimer)
{
    connect(m_timer,SIGNAL(timeout()),this,SLOT(timer()));
    m_timer->start(100);
}

void QPipelineWidth::setLineWidth(int lineWidth)
{
    if(lineWidth<8)
    {
        lineWidth=8;
    }
    if(m_line_width!=lineWidth)
    {
        m_line_width=lineWidth;
        update();
    }
}

int QPipelineWidth::speed()
{
    return m_speed;
}

void QPipelineWidth::setSpeed(int speed)
{
    if(speed<0 || speed>=11)
    {
        speed=1;
    }
    if(m_speed!=speed)
    {
        m_speed=speed;
        m_timer->stop();
        m_timer->start(g_speed[m_speed]);
    }
}

int QPipelineWidth::lineWidth()
{
    return m_line_width;
}

void QPipelineWidth::timer()
{
    m_point=m_point+=0.4;
    if(m_point>=3.8)
    {
        m_point=0;
    }
    this->update();
}

void QPipelineWidth::paintEvent(QPaintEvent *)
{
    QPainter p(this);

    p.setRenderHint(QPainter::Antialiasing,true);

    QPointFs ps=property("line_points").value<QPointFs>();

    if(ps.size()<2)
    {
        return;
    }

    QPoint* pt=new QPoint[ps.size()];

    int wid=this->width()-1-m_line_width*2;
    int hei=this->height()-1-m_line_width*2;

    int _x=m_line_width;
    int _y=m_line_width;

    QPainterPath path;
    path.moveTo(_x+(int)(wid*ps.first().x()),_y+(int)(hei*ps.first().y()));

    for(int i=1;i<ps.size();i++)
    {
        QPointF pf=ps.at(i);
        path.lineTo(_x+(int)(wid*pf.x()),_y+(int)(hei*pf.y()));
    }

    QPainterPathStroker stroker;
    stroker.setJoinStyle(Qt::RoundJoin);
    stroker.setWidth(m_line_width);
    stroker.setDashPattern(Qt::SolidLine);

    QPainterPath ppath=stroker.createStroke(path);

    QGradient g=property("frame_color").value<QGradient>();
    p.setPen(QPen(g,2));
    p.setBrush(QBrush(g));
    p.drawPath(ppath);

    g=property("line_color_1").value<QGradient>();
    stroker.setWidth(m_line_width-4);
    ppath=stroker.createStroke(path);
    p.fillPath(ppath,QBrush(g));

    g=property("line_color_2").value<QGradient>();
    QVector<qreal> v;
    v<<1<<3;
    stroker.setDashPattern(v);
    stroker.setDashOffset(m_point);
    ppath=stroker.createStroke(path);
    p.fillPath(ppath,QBrush(g));
    delete [] pt;
}


QPipelineHost::QPipelineHost(QAbstractHost *parent):
    QWidgetHost(parent)
{
    this->setProperty("need_frame",true);
    setProperty("accept_drop",false);
    setProperty("edit_property","line_points");
}

void QPipelineHost::create_object()
{
    m_object=new QPipelineWidth;
    m_object->setObjectName("pipelineWidget");
}

QString QPipelineHost::get_show_name()
{
    return tr("Pipeline");
}

QString QPipelineHost::get_show_group()
{
    return tr("Extension");
}

QString QPipelineHost::get_show_icon()
{
    return ":/images/pipeline.png";
}

void QPipelineHost::init_property()
{
    QWidgetHost::init_property();

    remove_property("font");
    remove_property("enabled");
    remove_property("focusPolicy");
    remove_property("background");
    remove_property("border");
    remove_property("toolTip");
    remove_property("mouseMove");
    remove_property("mousePress");
    remove_property("mouseRelease");
    remove_property("doubleClick");

    QAbstractProperty* pro;

    pro=QPropertyFactory::create_property("Number");

    QPipelineWidth* wid=(QPipelineWidth*)m_object;
    if(pro!=NULL)
    {
        pro->set_property("name","line_width");
        pro->set_attribute("show_name",tr("Width"));
        pro->set_attribute("group","Attributes");
        m_object->setProperty("line_width",16);
        pro->set_attribute(ATTR_CAN_SAME,true);
        insert_property(pro);
    }

    pro=QPropertyFactory::create_property("PointFs");
    if(pro!=NULL)
    {
        pro->set_property("name","line_points");
        pro->set_attribute("show_name",tr("Points"));
        pro->set_attribute("group","Attributes");
        m_object->setProperty("line_points",pro->get_value());
        insert_property(pro);
    }

    pro=QPropertyFactory::create_property("Color");
    if(pro!=NULL)
    {
        pro->set_property("name","line_color_1");
        pro->set_attribute("show_name",tr("Color 1"));
        pro->set_attribute("group","Attributes");
        QLinearGradient g;
        g.setColorAt(0,QColor(255,255,255));
        g.setColorAt(1,QColor(255,255,255));
        m_object->setProperty("line_color_1",QVariant::fromValue<QGradient>(g));
        pro->set_attribute(ATTR_CAN_SAME,true);
        connect(pro,SIGNAL(refresh()),wid,SLOT(update()));
        insert_property(pro);
    }

    pro=QPropertyFactory::create_property("Color");
    if(pro!=NULL)
    {
        pro->set_property("name","line_color_2");
        pro->set_attribute("show_name",tr("Color 2"));
        pro->set_attribute("group","Attributes");
        m_object->setProperty("line_color_2",pro->get_value());
        pro->set_attribute(ATTR_CAN_SAME,true);
        connect(pro,SIGNAL(refresh()),wid,SLOT(update()));
        insert_property(pro);
    }

    pro=QPropertyFactory::create_property("Color");
    if(pro!=NULL)
    {
        pro->set_property("name","frame_color");
        pro->set_attribute("show_name",tr("Frame Color"));
        pro->set_attribute("group","Attributes");
        m_object->setProperty("frame_color",pro->get_value());
        pro->set_attribute(ATTR_CAN_SAME,true);
        connect(pro,SIGNAL(refresh()),wid,SLOT(update()));
        insert_property(pro);
    }

    pro=QPropertyFactory::create_property("Enum");
    if(pro!=NULL)
    {
        pro->set_property("name","speed");
        pro->set_attribute("show_name",tr("Speed"));
        pro->set_attribute("group","Attributes");
        pro->set_attribute(ATTR_CAN_SAME,true);
        ComboItems items;
        tagComboItem item;

        for(int i=0;i<11;i++)
        {
            item.m_text=tr("Speed ")+QString::number(i+1);
            item.m_value=i;
            items.append(item);
        }

        QVariant v;
        v.setValue<ComboItems>(items);
        pro->set_attribute("items",QVariant::fromValue<ComboItems>(items));
        m_object->setProperty("speed",1);
        insert_property(pro);
    }



    set_property_value("geometry",QRect(0,0,100,100));
}

void QPipelineHost::setLineWidth(int lineWidth)
{
    set_property_value("line_width",lineWidth);
}

int QPipelineHost::lineWidth()
{
    return get_property_value("line_width").toInt();
}

qRegisterHost("extension.pipeline",QPipelineHost,4000)
